package org.example.mallcommon.tool;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Deserializer;
import io.jsonwebtoken.jackson.io.JacksonDeserializer;
import io.jsonwebtoken.jackson.io.JacksonSerializer;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import org.example.mallcommon.projo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 韩先楚
 * jwt工具类
 */
@Component
public class JwtUtil {
    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Autowired
    private ObjectMapper objectMapper;


    /**
     * 生成JWT Token
     */
    public String generateToken(User user) {
        // 1. 将密钥转换为安全格式
        SecretKey key = getSigningKey();

        // 2. 设置Token过期时间
        Date expireDate = new Date(System.currentTimeMillis() + expiration * 1000 * 3600);

        try {
            // 3. 构建JWT
            String jwt = Jwts.builder()
                    .claim("user", objectMapper.writeValueAsString(user))
                    .setIssuedAt(new Date()) // 签发时间
                    .setExpiration(expireDate) // 过期时间
                    .signWith(key, SignatureAlgorithm.HS256) // 签名算法
                    .compact();
            return jwt;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * 解析JWT Token
     */
    public User parseToken(String token) {
        try {
            Claims body = Jwts.parserBuilder()
                    .setSigningKey(getSigningKey())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            return objectMapper.readValue(body.get("user").toString(), User.class);
        } catch (ExpiredJwtException e) {
            throw new RuntimeException("Token已过期", e);
        } catch (SignatureException e) {
            throw new RuntimeException("Token签名无效", e);
        } catch (Exception e) {
            throw new RuntimeException("Token解析失败", e);
        }
    }

    /**
     * 验证JWT Token是否有效
     */
    public boolean validateToken(String token) {
        try {
            parseToken(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 生成安全的签名密钥
     */
    private SecretKey getSigningKey() {
        byte[] keyBytes = Decoders.BASE64.decode(secret);
        return Keys.hmacShaKeyFor(keyBytes);
    }


}
